/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
 */

package com.huawei.rpc.client.network;

import com.huawei.rpc.annotation.Service;
import com.huawei.rpc.client.network.handler.SendHandler;
import com.huawei.rpc.common.info.ServiceInfo;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;

/**
 * @Author Lijl
 * @ClassName NettyNetWorkClient
 * @Description Netty网络请求客户端，定义通过Netty实现网络请求
 * @Date 2022/2/14 16:35
 * @Version 1.0
 */
@Slf4j
public class NettyNetWorkClient implements NetWorkClient{

    /**
     * @Author lijl
     * @MethodName sendRequest
     * @Description 发送请求
     * @Date 16:36 2022/2/14
     * @Version 1.0
     * @param data 请求数据
     * @param serviceInfo 服务信息
     * @return: byte[] 响应数据
    **/
    @Override
    public byte[] sendRequest(byte[] data, ServiceInfo serviceInfo) throws InterruptedException {
        String[] addrInfoArray = serviceInfo.getAddress().split(":");
        String serverAddress = addrInfoArray[0];
        String serverPort = addrInfoArray[1];
        SendHandler sendHandler = new SendHandler(data);
        byte[] respData;
        NioEventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY,true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline pipeline = socketChannel.pipeline();
                            pipeline.addLast(sendHandler);
                        }
                    });
            bootstrap.connect(serverAddress,Integer.parseInt(serverPort)).sync();
            respData = (byte[]) sendHandler.rspData();
            log.info("SendRequest get reply: {}",respData);
        } finally {
            //释放线程组资源
            group.shutdownGracefully();
        }
        return respData;
    }
}
